package cn.wqb.bpp.common.utils;

import cn.wqb.bpp.common.entity.Result;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;

import javax.servlet.http.HttpServletRequest;

public class SMSCodeUtils {

    private final static String SessionKeyForTimestamp = "SessionKeyForTimestamp";
    private final static String SessionKeyForPhone = "SessionKeyForPhone";
    private final static String SessionKeyForCode = "SessionKeyForCode";
    //阿里云短信模板
    private static final String AccessKeyId = "LTAI4Fcx1cgDCHVkwkRnBdG3";
    private static final String AccessKeySecret = "BEpzWQyLQb4ykzw5AIFAizklAjbiAN";

    /**
     * 发送短信验证码
     *
     * @param phone 接收短信的手机号
     * @return 成功则返回true
     */
    public static Result sendSMSCode(HttpServletRequest request, String phone) {
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", AccessKeyId, AccessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        String code = getRandomCode();
        CommonRequest req = new CommonRequest();
        req.setSysMethod(MethodType.POST);
        req.setSysDomain("dysmsapi.aliyuncs.com");
        req.setSysVersion("2017-05-25");
        req.setSysAction("SendSms");
        req.putQueryParameter("RegionId", "cn-hangzhou");
        req.putQueryParameter("PhoneNumbers", phone);
        req.putQueryParameter("SignName", "2020疫情动态");
        req.putQueryParameter("TemplateCode", "SMS_183761525");
        req.putQueryParameter("TemplateParam", "{\"code\":\"" + code + "\"}");
        try {
            CommonResponse response = client.getCommonResponse(req);
            JSONObject json = JSONObject.parseObject(response.getData());
            if (json != null) {
                String returnCode = json.getString("Code");
                if ("isv.BUSINESS_LIMIT_CONTROL".equals(returnCode)) {
                    return Result.fail("同一个号码请求太频繁");
                } else if ("OK".equals(returnCode)) {
                    System.out.println("=============发送的验证码:" + code);
                    recordPhoneAndCode(request, phone, code, 600);
                    return Result.success(null);
                }
            }
            System.out.println("json:" + json.toJSONString());
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return Result.fail("短信发送失败");
    }

    private static String getRandomCode() {
        int randomValue = (int) ((Math.random() * 9 + 1) * 100000);
        return randomValue + "";
    }

    /**
     * 判断请求间隔是否小于60秒
     */
    public static boolean isIntervalLess60s(HttpServletRequest request) {
        Object previousTimestampObj = SessionUtils.getSession(request, SessionKeyForTimestamp);
        if (previousTimestampObj != null) {
            if (System.currentTimeMillis() - (long) previousTimestampObj < 1000 * 60) {
                return true;
            }
        }
        return false;
    }

    /**
     * 记录本次验证码请求
     * @param seconds 输入0或负数则Session永不超时
     */
    public static void recordPhoneAndCode(HttpServletRequest request, String phone, String code, int seconds) {
        SessionUtils.setSession(request, SessionKeyForTimestamp, System.currentTimeMillis(), seconds);
        SessionUtils.setSession(request, SessionKeyForPhone, phone, seconds);
        SessionUtils.setSession(request, SessionKeyForCode, code, seconds);
    }

    /**
     * 判断上传的手机号和验证码是否有效
     */
    public static boolean isValidPhoneAndCode(HttpServletRequest request, String phone, String code) {
        Object phoneObj = SessionUtils.getSession(request, SessionKeyForPhone);
        Object codeObj = SessionUtils.getSession(request, SessionKeyForCode);
        System.out.println("验证：" + phone + "|" + code + "|" + phoneObj + "|" + codeObj);
        if (phone != null && code != null && phoneObj != null && codeObj != null) {
            return phone.equals(phoneObj) && code.equals(codeObj);
        }
        return false;
    }

}
